namespace torch.plugin_manager;

public class PluginDownloader
{
    private readonly string _pluginDirectory;
    private readonly HttpClient _httpClient;

    public PluginDownloader(string pluginDirectory)
    {
        _pluginDirectory = pluginDirectory;
        _httpClient = new HttpClient();

        // 确保插件目录存在
        if (!Directory.Exists(_pluginDirectory))
        {
            Directory.CreateDirectory(_pluginDirectory);
        }
    }

    /// <summary>
    /// 下载插件并保存到本地
    /// </summary>
    /// <param name="pluginUrl">插件下载地址</param>
    /// <param name="fileName">保存的文件名</param>
    /// <param name="progress">下载进度回调</param>
    /// <returns>本地文件路径</returns>
    public async Task<string> DownloadPluginAsync(
        string pluginUrl,
        string fileName,
        IProgress<double>? progress = null)
    {
        try
        {
            // 获取文件大小（用于进度计算）
            using var headRequest = new HttpRequestMessage(HttpMethod.Head, pluginUrl);
            using var headResponse = await _httpClient.SendAsync(headRequest);
            headResponse.EnsureSuccessStatusCode();

            var fileSize = headResponse.Content.Headers.ContentLength ?? 0;
            var localPath = Path.Combine(_pluginDirectory, fileName);

            // 下载文件
            using var response = await _httpClient.GetAsync(pluginUrl, HttpCompletionOption.ResponseHeadersRead);
            response.EnsureSuccessStatusCode();

            using var stream = await response.Content.ReadAsStreamAsync();
            using var fileStream = new FileStream(localPath, FileMode.Create, FileAccess.Write);

            var buffer = new byte[8192];
            var totalBytesRead = 0L;
            int bytesRead;

            while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0)
            {
                await fileStream.WriteAsync(buffer, 0, bytesRead);
                totalBytesRead += bytesRead;

                // 报告进度
                if (fileSize > 0 && progress != null)
                {
                    var percent = (double)totalBytesRead / fileSize * 100;
                    progress.Report(percent);
                }
            }

            return localPath;
        }
        catch (Exception ex)
        {
            // 处理下载错误
            throw new Exception($"插件下载失败: {ex.Message}", ex);
        }
    }
}